package com.hex.ds.hdtp.core.web.metadata.controller;

import com.hex.bigdata.hbda.annotation.Log;
import com.hex.ds.hdtp.core.app.common.page.dto.PageDto;
import com.hex.ds.hdtp.core.app.metadata.service.ISourceInfoService;
import com.hex.ds.hdtp.core.inf.metadata.po.SourceInfoPo;
import com.hex.ds.hdtp.core.web.common.page.PageVo;
import com.hex.ds.hdtp.core.web.common.page.converter.IPageVoAndPageDtoConverter;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.Map;

/**
 * @Package: com.hex.hdc.web.cluster.controller
 * @ClassName DataSourceInfoController
 * @Description: 数据源管理
 * @Author: tj
 * @Date 2021-06-29 10:38
 * @Version v1.0
 **/
@Slf4j
@RestController
@Api(tags = "00-准备工作：系统配置（数据源）")
@RequestMapping("/api/sourceInfo")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SourceInfoController {

    private final ISourceInfoService sourceInfoService;

    private final IPageVoAndPageDtoConverter pageVoAndPageDtoConverter;

    /**
     * @Method: findListByPage <br>
     * @Param: [queryVo, pageInfo] <br>
     * @Return: org.springframework.http.ResponseEntity <br>
     * @Description：分页查询 <br>
     * @Author： lwz <br>
     * @Date： 2021/11/8 17:41 <br>
     * @Version： V1.0<br>
     */
    @GetMapping
    @ApiOperation("数据源分页查询")
    public ResponseEntity findListByPage(SourceInfoPo sourceInfoPo, PageVo pageVo) {
        log.info("进入【SourceInfoController.findListByPage】方法,参数：{}", sourceInfoPo.toString());
        final PageDto pageDto = pageVoAndPageDtoConverter.toPageDto(pageVo);
        return ResponseEntity.ok(sourceInfoService.queryListByPage(sourceInfoPo, pageDto));
    }

    /**
     * @Method findDefaultSource
     * @Param
     * @Return org.springframework.http.ResponseEntity
     * @Description 获取默认数据源
     * @Author gj.xu
     * @Date 2023/12/21 10:02
     * @Version V2.0
     */
    @GetMapping(value = "/findDefaultSource")
    @ApiOperation("获取默认数据源")
    public ResponseEntity findDefaultSource() {
        log.info("进入【SourceInfoController.findDefaultSource】方法");
        return ResponseEntity.ok(sourceInfoService.findDefaultSource());
    }

    /*
     * @Method: findListByCheck <br>
     * @Param: [checkSourceInfoVo, pageVo] <br>
     * @Return: org.springframework.http.ResponseEntity <br>
     * @Description：全表检测数据源是否已经存在<br>
     * @Author： wz.li<br>
     * @Date： 2022/5/6 14:53 <br>
     * @Version： V2.0.2<br>
     */
    @GetMapping(value = "/check")
    @ApiOperation("检查数据源")
    public ResponseEntity findListByCheck(SourceInfoPo sourceInfoPo) {
        log.info("进入【SourceInfoController.findListByCheck】方法");
        SourceInfoPo sourceInfo = sourceInfoService.checkSourceCode(sourceInfoPo.getSourceCode());
        return ResponseEntity.ok(sourceInfo);
    }

    /*
     * @Method: add <br>
     * @Param: [sourceInfoVo] <br>
     * @Return: org.springframework.http.ResponseEntity <br>
     * @Description：新增数据源<br>
     * @Author： wz.li<br>
     * @Date： 2022/5/6 14:54 <br>
     * @Version： V2.0.2<br>
     */
    @Log("新增数据源")
    @PostMapping
    @ApiOperation("新增数据源")
    public ResponseEntity add(@RequestBody SourceInfoPo sourceInfoPo) {
        log.info("进入【SourceInfoController.add】方法,参数sourceInfoVo:{}", sourceInfoPo.toString());
        sourceInfoService.add(sourceInfoPo);
        return ResponseEntity.ok("新增成功");
    }

    @Log("更新数据源")
    @PutMapping
    @ApiOperation("更新数据源")
    public ResponseEntity update(@RequestBody SourceInfoPo sourceInfoPo) {
        log.info("进入到【SourceInfoController.update】方法,参数：{}" + sourceInfoPo.toString());
        sourceInfoService.modifyById(sourceInfoPo);
        return ResponseEntity.ok("更新成功");
    }

    @Log("更新是否默认")
    @PutMapping(value = {"/updateIsDefault"})
    @ApiOperation("更新是否默认")
    public ResponseEntity updateIsDefault(@RequestBody SourceInfoPo sourceInfoPo) {
        log.info("进入到【SourceInfoController.updateIsDefault】方法,参数：{}" + sourceInfoPo.toString());
        sourceInfoService.modifyIsDefault(sourceInfoPo);
        return ResponseEntity.ok("更新是否默认成功");
    }

    @Log("删除数据源")
    @DeleteMapping
    @ApiOperation("删除数据源")
    public ResponseEntity delete(@RequestBody List<String> pkIds) {
        log.info("进入到【SourceInfoController.delete】方法,参数：{}" + pkIds.toString());
        sourceInfoService.removeByIds(pkIds);
        return ResponseEntity.ok("删除成功");
    }

    /**
     * @Method: getSourceInfo <br>
     * @Param: [pkId] <br>
     * @Return: org.springframework.http.ResponseEntity <br>
     * @Description：获取某个数据源配置信息 <br>
     * @Author： lwz <br>
     * @Date： 2021/8/29 16:39 <br>
     * @Version： V1.0<br>
     */
    @GetMapping(value = {"/{pkId}"})
    @ApiOperation("获取某个数据源的配置信息")
    public ResponseEntity getSourceInfo(@PathVariable("pkId") final String pkId) {
        log.info("进入了【SourceInfoController.getSourceInfo】方法,参数pkId: {}", pkId);
        return ResponseEntity.ok(sourceInfoService.queryByPkId(pkId));
    }

    @GetMapping(value = {"/testConnect/{pkId}"})
    @ApiOperation("获取某个数据源的配置信息")
    public ResponseEntity testConnectById(@PathVariable("pkId") final String pkId) {
        log.info("进入了【SourceInfoController.testConnect】方法,参数pkId: {}", pkId);
        sourceInfoService.testConnectById(pkId);
        return ResponseEntity.ok("测试连接成功！");
    }

    @PostMapping(value = "/testConnect")
    @ApiOperation("测试连接")
    public ResponseEntity testConnect(@RequestBody SourceInfoPo sourceInfoPo) {
        log.info("进入【SourceInfoController.testConnect】方法,参数sourceInfoPo:{}", sourceInfoPo.toString());
        sourceInfoService.testConnect(sourceInfoPo);
        return ResponseEntity.ok("测试连接成功！");
    }

    @GetMapping(value = {"/schemas/{pkId}"})
    @ApiOperation("获取指定数据源下的所有库集合")
    public ResponseEntity schemas(@PathVariable("pkId") final String pkId) {
        log.info("进入了【SourceInfoController.schemas】方法,参数pkId: {}", pkId);
        return ResponseEntity.ok(sourceInfoService.schemas(pkId));
    }

    @GetMapping(value = {"/procedures"})
    @ApiOperation("获取指定数据源和指定库的所有存储过程")
    public ResponseEntity procedures(@RequestParam @NotBlank String pkId, @RequestParam @NotBlank String schema) {
        log.info("进入了【SourceInfoController.procedures】方法,参数pkId: {}, schema: {}", pkId, schema);
        return ResponseEntity.ok(sourceInfoService.procedures(pkId, schema));
    }

    @GetMapping(value = {"/tables"})
    @ApiOperation("获取指定数据源和指定库的所有表集合")
    public ResponseEntity tables(@RequestParam @NotBlank String pkId, @RequestParam @NotBlank String schema) {
        log.info("进入了【SourceInfoController.tables】方法,参数pkId: {}, schema: {}", pkId, schema);
        return ResponseEntity.ok(sourceInfoService.tables(pkId, schema));
    }

    @GetMapping(value = {"/tablesStructure"})
    @ApiOperation("获取指定数据源和指定库表的元数据")
    public ResponseEntity tablesStructure(@RequestParam @NotBlank String pkId, @RequestParam @NotBlank String schema, @RequestParam @NotBlank String table) {
        log.info("进入了【SourceInfoController.tablesStructure】方法,参数pkId: {}, schema: {}, table: {}", pkId, schema, table);
        return ResponseEntity.ok(sourceInfoService.tablesStructure(pkId, schema, table));
    }

    @GetMapping(value = {"/tablesStructureTyped"})
    @ApiOperation("获取指定数据源和指定库表的元数据")
    public ResponseEntity tablesStructureByType(@RequestParam @NotBlank String pkId, @RequestParam @NotBlank String schema, @RequestParam @NotBlank String table, @RequestParam @NotBlank String fieldType) {
        log.info("进入了【SourceInfoController.tablesStructure】方法,参数pkId: {}, schema: {}, table: {} 字段类型：", pkId, schema, table);
        return ResponseEntity.ok(sourceInfoService.tablesStructureByType(pkId, schema, table, fieldType));
    }

    @GetMapping(value = {"/exportMetadata"})
    @ApiOperation("导出数据源")
    public ResponseEntity exportMetadata(@RequestParam List<String> pkIds) {
        log.info("进入了【SourceInfoController.exportMetadata】方法,List<String>: {}", pkIds);
        ByteArrayResource bar = sourceInfoService.exportMetadata(pkIds);
        return ResponseEntity.ok()
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .header("Content-disposition", "attachment; filename=SourceInfoTemplate")
                .body(bar);
    }

    @PostMapping(value = {"/importMetadata"})
    @ApiOperation("导入数据源")
    public ResponseEntity importMetadata(@RequestBody MultipartFile file) {
        log.info("进入了【SourceInfoController.importMetadata】方法,MultipartFile: {}", file);
        Map<String, Object> resultMap = sourceInfoService.importMetadata(file);
        return new ResponseEntity(resultMap, HttpStatus.OK);
    }

}
